package biz

import (
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"gitlab1.moolink.net/trade/backend/gen"
	"lab.com/conf"
	"lab.com/consts"
	"lab.com/gen/entity"
	"lab.com/request"
)

type fileBiz struct {
}

// File  文件信息
var File = fileBiz{}

// FileList 文件列表
func (forum *fileBiz) FileList(c *gin.Context, req request.FileListReq) (out request.FileListRes, err error) {
	ctx := conf.Span(c, "biz file list", nil)
	fileModel := conf.LabGen.File
	userID := strconv.Itoa(req.BaseUserInfo.UserID)
	where := []gen.Condition{fileModel.Status.Eq(consts.FileNormal), fileModel.Pid.Eq(req.PID)}
	if req.Name != "" {
		where = append(where, fileModel.Name.Like("%"+req.Name+"%"))
	}
	var info []*entity.File
	var count int64
	if req.PID != 0 { //继承上级，不用权限限制
		info, count, err = fileModel.WithContext(ctx).Where(where...).Order(fileModel.UpdateTime.Desc()).FindByPage(req.Offset, req.Size)
		if err!= nil {
            return out, err
        }
	} else { //顶级，设置权限
		info, count, err = fileModel.WithContext(ctx).Where(where...).Where(fileModel.WithContext(ctx).Where(fileModel.AccessType.Eq(consts.FileAccessOpen)).Or(fileModel.AccessType.Eq(consts.FileAccessOwner), fileModel.OwnerID.Eq(req.BaseUserInfo.UserID)).Or(fileModel.AccessType.Eq(consts.FileAccessCustom), fileModel.AccessUser.FindInSetWith(userID))).Order(fileModel.UpdateTime.Desc()).FindByPage(req.Offset, req.Size)
		if err != nil {
			return out, err
		}
	}

	ownerIDs := make([]int, 0)
	for _, val := range info {
		ownerIDs = append(ownerIDs, val.OwnerID)
	}
	userModel := conf.LabGen.User
	userInfos, err := userModel.WithContext(ctx).Where([]gen.Condition{userModel.ID.In(ownerIDs...)}...).Find()
	if err != nil {
		return out, err
	}
	userMap := make(map[int]entity.User)
	for _, val := range userInfos {
		userMap[val.ID] = *val
	}
	list := make([]request.FileBasicInfo, 0, len(info))
	for _, val := range info {
		list = append(list, request.FileBasicInfo{
			ID:         val.ID,
			Name:       val.Name,
			Type:       val.Type,
			OwnerID:    val.OwnerID,
			OwnerName:  userMap[val.OwnerID].Username,
			CreateTime: val.CreateTime.Format("2006-01-02 15:04:05"),
			UpdateTime: val.UpdateTime.Format("2006-01-02 15:04:05"),
		})
	}
	out.List = list
	out.Count = int(count)
	return out, nil
}

// FileAdd 文件新增
func (file *fileBiz) FileAdd(c *gin.Context, req request.FileAddReq) (err error) {
	ctx := conf.Span(c, "biz file add", nil)
	fileModel := conf.LabGen.File
	var accessType int
	var accessUsers string
	//顶级文件夹设置权限，内部文件夹与文件权限和其一致
	if req.PID == 0 {
		accessType = req.AccessType
		accessUsers = req.AccessUsers
	}
	info := &entity.File{
		Name:       req.Name,
		Type:       req.Type,
		AccessType: accessType,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
		Pid:        req.PID,
		AccessUser: accessUsers,
		Status:     consts.FileNormal,
		OwnerID:    req.UserID,
	}

	err = fileModel.WithContext(ctx).Create(info)
	if err != nil {
		return err
	}
	return nil
}

// FileRename 文件重命名
func (file *fileBiz) FileRename(c *gin.Context, req request.FileRenameReq) (err error) {
	ctx := conf.Span(c, "biz file rename", nil)
	fileModel := conf.LabGen.File

	info := &entity.File{
		Name:       req.Name,
		UpdateTime: time.Now(),
	}

	_, err = fileModel.WithContext(ctx).Select(fileModel.Name, fileModel.UpdateTime).Where(fileModel.ID.Eq(req.ID)).Updates(info)
	if err != nil {
		return err
	}
	return nil
}

// FileDelete文件删除
func (file *fileBiz) FileDelete(c *gin.Context, req request.FileDeleteReq) (err error) {
	ctx := conf.Span(c, "biz file delete", nil)
	fileModel := conf.LabGen.File

	info := &entity.File{
		Status:     consts.FileDelete,
		UpdateTime: time.Now(),
	}

	_, err = fileModel.WithContext(ctx).Select(fileModel.Status, fileModel.UpdateTime).Where(fileModel.ID.Eq(req.ID)).Updates(info)
	if err != nil {
		return err
	}
	return nil
}

// FileEdit 文件编辑
func (file *fileBiz) FileEdit(c *gin.Context, req request.FileEditReq) (err error) {
	ctx := conf.Span(c, "biz file edit", nil)
	fileModel := conf.LabGen.File

	info := &entity.File{
		Content:    req.Content,
		UpdateTime: time.Now(),
	}

	_, err = fileModel.WithContext(ctx).Select(fileModel.Content, fileModel.UpdateTime).Where(fileModel.ID.Eq(req.ID)).Updates(info)
	if err != nil {
		return err
	}
	return nil
}

// FileAccessEdit 文件夹权限编辑
func (file *fileBiz) FileAccessEdit(c *gin.Context, req request.FileAccessEditReq) (err error) {
	ctx := conf.Span(c, "biz file access edit", nil)
	fileModel := conf.LabGen.File

	info := &entity.File{
		AccessType: req.AccessType,
		AccessUser: req.AccessUsers,
		UpdateTime: time.Now(),
	}

	_, err = fileModel.WithContext(ctx).Select(fileModel.Content, fileModel.UpdateTime).Where(fileModel.ID.Eq(req.ID)).Updates(info)
	if err != nil {
		return err
	}
	return nil
}
